﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.Windows;

namespace WpfConsole.ConsoleTest
{

    [TestFixture]
    public class MouseSelectionTest
    {
        const int _fontWidth = 10;
        const int _fontHeight = 20;

        MouseSelection _selection;

        [SetUp]
        public void Setup()
        {
            _selection = new MouseSelection(_fontWidth, _fontHeight);
        }

        [Test]
        public void TestSelecting_DefaultFalse()
        {
            Assert.IsFalse(_selection.Selecting);
        }

        [Test]
        public void TestSelecting_MouseDown_True()
        {
            _selection.MouseDown(new Point(5, 5));
            Assert.IsTrue(_selection.Selecting);
        }

        [Test]
        public void TestSelecting_MouseDownTwice_True()
        {
            _selection.MouseDown(new Point(5, 5));
            _selection.MouseDown(new Point(5, 5));
            Assert.IsTrue(_selection.Selecting);
        }

        [Test]
        public void TestSelecting_MouseDownMouseMove_True()
        {
            _selection.MouseDown(new Point(5, 5));
            _selection.MouseMove(new Point(5, 5));
            Assert.IsTrue(_selection.Selecting);
        }

        [Test]
        public void TestSelecting_MouseDownMouseUp_False()
        {
            _selection.MouseDown(new Point(5, 5));
            _selection.MouseUp(new Point(5, 5));
            Assert.IsFalse(_selection.Selecting);
        }

        [Test]
        public void TestHasSelection_DefaultFalse()
        {
            Assert.IsFalse(_selection.HasSelection);
        }

        [Test]
        public void TestHasSelection_MouseDown_True()
        {
            _selection.MouseDown(new Point(5, 5));
            Assert.IsTrue(_selection.HasSelection);
        }

        [Test]
        public void TestHasSelection_MouseDownTwice_True()
        {
            _selection.MouseDown(new Point(5, 5));
            _selection.MouseDown(new Point(5, 5));
            Assert.IsTrue(_selection.HasSelection);
        }


        [Test]
        public void TestHasSelection_MouseDownMouseUp_True()
        {
            _selection.MouseDown(new Point(5, 5));
            _selection.MouseUp(new Point(5, 5));
            Assert.IsTrue(_selection.HasSelection);
        }


        [Test]
        public void TestCreateGridCoord_Origin_FirstRowFirstCol()
        {
            Rect expected = new Rect(0, 0, 0, 0);
            Rect actual = _selection.CreateGridCoord(new Point(0, 0), new Point(0, 0));
            AssertRect(expected, actual);
        }

        [Test]
        public void TestCreateGridCoord_PlusXPlusY_TwoRowTwoCol()
        {
            Rect expected = new Rect(0, 0, 1, 1);
            Rect actual = _selection.CreateGridCoord(new Point(0, 0), new Point(_fontWidth + 1, _fontHeight+1));
            AssertRect(expected, actual);
        }

        [Test]
        public void TestCreateGridCoord_LittleMinusXLittleMinusY_OneRowOneCol()
        {
            Rect expected = new Rect(0, 0, 0, 0);
            Rect actual = _selection.CreateGridCoord(new Point(1, 1), new Point(0, 0));
            AssertRect(expected, actual);
        }

        [Test]
        public void TestCreateGridCoord_MinusXMinusY_OneRowOneCol()
        {
            Rect expected = new Rect(0, 0, 1, 1);
            Rect actual = _selection.CreateGridCoord(new Point(_fontWidth + 0.1, _fontHeight+0.1), new Point(0, 0));
            AssertRect(expected, actual);
        }

        [Test]
        public void TestCreateRegion_Origin_FirstRowFirstCol()
        {
            Rect expected = new Rect(0, 0, _fontWidth, _fontHeight);
            Rect actual = _selection.CreateRegion(new Point(0, 0), new Point(0, 0));
            AssertRect(expected, actual);
        }

        [Test]
        public void TestCreateRegion_PlusXPlusY_TwoRowTwoCol()
        {
            Rect expected = new Rect(0, 0, 2*_fontWidth, 2*_fontHeight);
            Rect actual = _selection.CreateRegion(new Point(0, 0), new Point(_fontWidth+1, _fontHeight+1));
            AssertRect(expected, actual);

        }

        [Test]
        public void TestCreateRegion_OneOne_OneRowOneCol()
        {
            Rect expected = new Rect(_fontWidth, _fontHeight, _fontWidth, _fontHeight);
            Rect actual = _selection.CreateRegion(new Point(_fontWidth+1, _fontHeight+1), new Point(_fontWidth + 1, _fontHeight + 1));
            AssertRect(expected, actual);

        }

        [Test]
        public void TestCreateRegion_MinusXMinusY_TwoRowTwoCol()
        {
            Rect expected = new Rect(0, 0, _fontWidth*2, _fontHeight*2);
            Rect actual = _selection.CreateRegion(new Point(_fontWidth + 1, _fontHeight + 1), new Point(_fontWidth-1, _fontHeight - 1));
            AssertRect(expected, actual);

        }

        private void AssertRect(Rect expected, Rect actual)
        {
            Assert.AreEqual(expected.X, actual.X, 0.05, "assertRect:X");
            Assert.AreEqual(expected.Y, actual.Y, 0.05, "assertRect:Y");
            Assert.AreEqual(expected.Width, actual.Width, 0.05, "assertRect:W");
            Assert.AreEqual(expected.Height, actual.Height, 0.05, "assertRect:H");
        }
    }
}
